#include "pwext.hpp"
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/signal.h>

// [[ex05bb]]
// DEBUG descr A signal used to interrupt the sleeping thread.
class worker : public pw::pwthread
{
public:
	// DEBUG {
	worker() : 
		exit_flag_(false)
	{ }
	void *execute()
	{
		while(!get_exit_flag()) {
			char bf[10];
			int r = ::read(0, bf, sizeof(bf));
			fprintf(stderr, "Read %d bytes errno=%d %s\n", r, errno, strerror(errno));
		}
		return 0;
	}
	// DEBUG }
	// ...
	void stop()
	{
		{
			pw::lockmutex lm(exit_mutex_);
			exit_flag_ = true;
		}
		exit_event_.signal();
		if (id_ != 0)
			// id_ is inherited from pw::thread
			pthread_kill(id_, SIGUSR1); 
	}
	// ...
	// DEBUG {
protected:
	bool get_exit_flag()
	{
		pw::lockmutex lm(exit_mutex_);
		return exit_flag_;
	}

	bool exit_flag_;
	pw::pmutex exit_mutex_;
	pw::event exit_event_;
	// DEBUG }
};
// END

// [[ex05ba]]
// DEBUG descr Setting up an empty signal handler.
void dummyhandler(int sig)
{ }

int main(int argc, char **argv)
{
	// ...
	struct sigaction sa;
	sa.sa_handler = dummyhandler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0; // do not specify SA_RESTART !!!
	sigaction(SIGUSR1, &sa, NULL);
	// ...
	// DEBUG {
	worker w;
	w.start();
	sleep(1);
	w.stop();
	w.join();
	// DEBUG }
}
// END

/* Sample output:
Read -1 bytes errno=4 Interrupted system call
*/
